Enterprise Objects Framework Release 1.1 Copyright ã1995 by NeXT Computer, Inc.  All Rights Reserved.

EOAdaptor

Inherits From:	NSObject

Declared In:	eoaccess/EOAdaptor.h

Class Description

An EOAdaptor represents a single connection to a database server, and is responsible for keeping login and model information, performing server-specific formatting of SQL expressions, and reporting errors. The EOAdaptor class also defines the methods that find and load adaptor bundles.

An EOAdaptor can manage several EOAdaptorContexts, each of which represents a transaction scope on the database server. An EOAdaptorContext can in turn manage several EOAdaptorChannels, each of which handles actual access to the data on the server. A newly created adaptor has no adaptor contexts; to create a new context send your adaptor a createAdaptorContext message. An adaptor for a particular database may support a limited number of contexts per adaptor object or channels per context, but an application is guaranteed at least one of each.

An EOAdaptorContext retains its adaptor when created and an EOAdaptorChannel retains its context, so when you create a set of these objects, you need only retain the channel for all objects to remain valid.

Creating an Adaptor and Connecting To The Server

You normally create an adaptor with an existing EOModel object, which in turn is usually defined with the EOModeler application (see the EOModel class specification for information on loading a model file). The EOModel contains the name of the adaptor bundle it needs, and also contains connection information so that an application can connect immediately without requiring the user to type a password.

This connection information is a dictionary containing items needed to connect to the database server, such as user name and password. The keys of this dictionary identify the information the server expects, and the values of those keys are the values that the adaptor will try when connecting. Different adaptors may use different keys; see your adaptor's documentation for keys it uses.

You can create a connection dictionary and assign it to your adaptor with the setConnectionDictionary: method, or you can have the adaptor run a login panel to get the information from the user. When you ask an adaptor to validate its connection dictionary with the runLoginPanelAndValidateConnectionDictionary message, it briefly forms a connection to confirm that the server will accept the values entered by the user. An adaptor doesn't form a lasting connection to the database server until it receives an openChannel message.

The following code excerpt shows one way to set up a suite of adaptor objects, given a model that's already loaded:

EOModel *myModel;    /* Assume this exists. */
EOAdaptor *myAdaptor;
EOAdaptorContext *myContext;
EOAdaptorChannel *myChannel;

myAdaptor = [EOAdaptor adaptorWithModel:myModel];
myContext = [myAdaptor createAdaptorContext];
myChannel = [[myContext createAdaptorChannel] retain];

if ([myAdaptor hasValidConnectionDictionary] == NO &&
    [myAdaptor runLoginPanelAndValidateConnectionDictionary] == NO) {
    /* Handle user canceling login panel... */
}

if ([myChannel openChannel] == NO) {
    /* Handle error... */
}

The section beginning with the invocation of hasValidConnectionDictionary makes sure that the adaptor has the information needed to log in to the server. If the connection dictionary doesn't have valid information (for example, it's common to leave the user name and password unspecified in the model file), runLoginPanelAndValidateConnectionDictionary is invoked to allow the user to enter the necessary connection information. The invocation of openChannel at the end of the excerpt causes the application to form a connection to the database.

Formatting of SQL Expressions

An adaptor plays a role in the formatting of SQL for its database server. The formatAttribute: and formatValue:forAttribute: methods are automatically invoked in the generation of SQL to guarantee that references to attributes and their values are in proper form for the database server SQL interpreter. For example, a string value must be quoted before being sent to the server, so formatValue:forAttribute: adds the proper quotation and escape characters:

Unformatted	Formatted

Tom's Diner	'Tom''s Diner'

Similarly, an adaptor is responsible for knowing the formatting requirements of special database types, such as money, adding whatever characters or modifications are needed for proper representation of the value in SQL:

Unformatted	Formatted

3000.00	$3000.00

You never normally invoke these formatting methods, but if you're creating your own adaptor you need to override them.

Notifying the Adaptor's Delegate

EOAdaptor offers a single delegate message: adaptor:willReportError:. This message allows an adaptor's delegate to handle error reporting on its own. All a delegate need do to receive this message is implement it; if the delegate doesn't respond to this message it's never sent. Server-specific adaptors may declare their own error-reporting delegate messages; an adaptor's documentation will include descriptions of any such messages.

Instance Variables

 None declared in this class.

Method Types

Creating an EOAdaptor	+ adaptorWithModel:
+ adaptorWithName:
- initWithName:

Getting an adaptor's name	- name

Setting connection information	- setConnectionDictionary:
- connectionDictionary
- hasValidConnectionDictionary
- runLoginPanel
- runLoginPanelAndValidateConnectionDictionary

Setting the model	- setModel:
- model

Creating an adaptor context	- createAdaptorContext

Checking connection status	- hasOpenChannels

Getting adaptor-specific information
- expressionClass
- isValidQualifierType:

Formatting SQL	- formatAttribute:
- formatValue:forAttribute:

Reporting errors	- reportError:

Setting the delegate	- setDelegate:
- delegate

Class Methods

adaptorWithModel:

+ adaptorWithModel:(EOModel *)aModel

Creates and returns a new adaptor by extracting the adaptor name from aModel, sending adaptorWithName: to self, and assigning aModel and aModel's connection dictionary to the new adaptor. A subclass of EOAdaptor shouldn't override this method.

See also:  - adaptorName: (EOModel), - setModel:, - setConnectionDictionary:

adaptorWithName:

+ adaptorWithName:(NSString *)name

Creates and returns a new adaptor, sending it an initWithName: message and loading it from the bundle named name. Searches the application's main bundle, ~/Library/Adaptors, /LocalLibrary/Adaptors, and /NextLibrary/Adaptors, in that order, for the first adaptor bundle whose base filename (that is, the filename without the .dbadaptor extension) matches name. For example, this code excerpt creates an adaptor from a bundle named Acme.dbadaptor:

EOAdaptor *myAdaptor = [EOAdaptor adaptorWithName:@"Acme"];

A subclass of EOAdaptor shouldn't override this method.

Instance Methods

connectionDictionary

- (NSDictionary *)connectionDictionary

Returns the adaptor's connection dictionary, or nil if the adaptor doesn't have one. The connection dictionary is also a property list (that is, it contains only NSString, NSData, NSDictionary, or NSArray objects). See the class description for information on connection dictionaries. A subclass of EOAdaptor doesn't need to override this method.

createAdaptorContext

- (EOAdaptorContext *)createAdaptorContext

Returns a new EOAdaptorContext, or nil if a new context can't be created. A newly created EOAdaptor has no contexts. The new context retains the adaptor.

A subclass of EOAdaptor must properly override this method without invoking EOAdaptor's implementation.

delegate

- delegate

Returns the adaptor's delegate. A subclass of EOAdaptor doesn't need to override this method.

expressionClass

- (Class)expressionClass

Returns the subclass of EOSQLExpression used by the adaptor for query language expressions. You never directly invoke this method, but an adaptor subclass must override it without invoking EOAdaptor's implementation.

formatAttribute:

- formatAttribute:(EOAttribute *)anAttribute

Returns an expression object that formats anAttribute for SQL SELECT statements sent to the adaptor's database server. You never directly invoke this method, but an adaptor subclass must override it without invoking EOAdaptor's implementation.

Expression objects are described in the EOExpression informal protocol specification.

See also:  - expressionValueForContext: (EOExpression informal protocol)

formatValue:forAttribute:

- formatValue:aValue forAttribute:(EOAttribute *)anAttribute

Returns an expression object for anAttribute that can provide a aValue properly formatted for a SQL SELECT, INSERT, or UPDATE statement. The formatted value will contain properly quoted and escaped strings, dates in the server's expected form, and so on. You never directly invoke this method, but an adaptor subclass must override it without invoking EOAdaptor's implementation.

Expression objects are described in the EOExpression informal protocol specification.

See also:  - expressionValueForContext: (EOExpression informal protocol)

hasOpenChannels

- (BOOL)hasOpenChannels

Returns YES if the adaptor has any open channels, NO otherwise. An adaptor subclass must override this method without invoking EOAdaptor's implementation.

See also:  - openChannel (EOAdaptorChannel class)

hasValidConnectionDictionary

- (BOOL)hasValidConnectionDictionary

Returns YES if the adaptor can connect with its connection dictionary, NO otherwise. This method briefly forms a connection to the server and then closes it. A full connection is made when the first adaptor channel is sent an openChannel message.

An adaptor subclass must override this method without invoking EOAdaptor's implementation.

initWithName:

- initWithName:(NSString *)name

Initializes a newly allocated EOAdaptor subclass with name, which is usually the base filename (that is, the filename without the .dbadaptor extension) of the bundle that the adaptor is loaded from. Returns self.

This is the designated initializer for the EOAdaptor class. You can use this method to initialize an adaptor you've allocated yourself; however, you must use the adaptorWithName: or adaptorWithModel: class methods to create a new adaptor from a bundle.

isValidQualifierType:

- (BOOL)isValidQualifierType:(NSString *)typeName

Returns YES if an attribute of type typeName can be used in a qualifier (a SQL WHERE clause) sent to the database server, otherwise returns NO. typeName is the name of a type as required by the database server, such as a Sybase ªvarcharº or an Oracle ªNUMBERº.

An adaptor subclass must override this method without invoking EOAdaptor's implementation.

model

- (EOModel *)model

Returns the model that describes the adaptor's database schema. A suite of adaptor objects must have a model to fetch or manipulate rows; unless you'll be building a model programmatically, you should create your adaptor with a model using the adaptorWithModel: class method.

A subclass of EOAdaptor doesn't need to override this method.

name

- (NSString *)name

Returns the adaptor's name; this is usually the base filename of the bundle the adaptor was loaded from. For example, if an adaptor was loaded from a bundle named Acme.dbadaptor, this method returns ªAcmeº.

A subclass of EOAdaptor doesn't need to override this method.

See also:  + adaptorWithName:, + initWithName:

reportError:

- (void)reportError:(NSString *)error

Adaptor-level objects send this message to their EOAdaptor to have errors reported to the user. The EOAdaptor first checks its delegate (if it has one) with adaptor:willReportError: to see if it will handle the error. If there is a delegate and it returns NO, the adaptor takes no further action.

If the delegate returns YES or doesn't respond to adaptor:willReportError:, the EOAdaptor tries to open an attention panel (this is only possible in a NEXTSTEP application). If there's no Application instance, it logs the error to the console or standard output.

A subclass of EOAdaptor doesn't need to override this method, but may provide a server-specific method that provides more information about errors.

runLoginPanel

- (NSDictionary *)runLoginPanel

Runs the adaptor's login panel, allowing the user to enter new connection information, and returns that information without affecting the adaptor's connection dictionary. Returns nil if the user clicks Cancel on the login panel. The connection dictionary returned isn't validated by this method.

A subclass of EOAdaptor doesn't need to override this method.

See also:  - runLoginPanelAndValidateConnectionDictionary, - setConnectionDictionary:, - hasValidConnectionDictionary

runLoginPanelAndValidateConnectionDictionary

- (BOOL)runLoginPanelAndValidateConnectionDictionary

Runs the adaptor's login panel until the user enters valid connection information or clicks Cancel. Valid login information entered in the panel is stored in the adaptor's connection dictionary. This method briefly forms a connection with the server to verify the connection information. Returns YES if the connection dictionary is validated, NO if the user clicks Cancel in the login panel.

A subclass of EOAdaptor doesn't need to override this method.

See also:  - runLoginPanel, - setConnectionDictionary:, - hasValidConnectionDictionary

setConnectionDictionary:

- (void)setConnectionDictionary:(NSDictionary *)aDictionary

Sets the adaptor's connection dictionary to aDictionary, which must be a property list (containing only NSString, NSData, NSDictionary, or NSArray objects). See the class description for information on connection dictionaries. Raises NSInvalidArgumentException if there are any open channelsÐyou can't change connection information while the adaptor is connected.

A subclass of EOAdaptor doesn't need to override this method.

See also:  - hasOpenChannels, - runLoginPanelAndValidateConnectionDictionary, - hasValidConnectionDictionary

setDelegate:

- (void)setDelegate:anObject

Sets the adaptor's delegate to anObject and retains it. A subclass of EOAdaptor doesn't need to override this method.

setModel:

- (void)setModel:(EOModel *)aModel

Sets the model used by the adaptor to aModel. Doesn't set the connection dictionary, even if aModel has one; this prevents the adaptor's own connection dictionary from being unintentionally overwritten.

A subclass of EOAdaptor doesn't need to override this method.

See also:  - setConnectionDictionary:, - connectionDictionary (EOModel)

Methods Implemented by the Delegate

adaptor:willReportError:

- (BOOL)adaptor:(EOAdaptor *)adaptor willReportError:(NSString *)error

An adaptor sends this message to its delegate when an error has occurred. If the delegate returns YES or doesn't respond to this message, the adaptor opens an attention panel (or logs the error to the console if it isn't in a NEXTSTEP application). If the delegate returns NO the adaptor takes no further action. error is the string that will appear in the attention panel or console.